/**
 * This class represents platform-dependent drawer, necessary for a
 * model to present visual data
 */

package org.amse.ys.sndeditor.model.drawer;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Looper;

import org.amse.ys.sndeditor.model.IDrawer;
import org.amse.ys.sndeditor.ui.SoundSaveDialog;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;

public class AndroidDrawer extends IDrawer {
	private Paint myPaint; // painting attributes
	private Canvas myCanvas; // active canvas
	private Bitmap myBitmap; // bitmap we return if nessesary
	private boolean myChanged; // onChanged flag
	private Context myContext;
	public static AndroidDrawer myDrawerInctance;
	public static Object myActionToDo;
	private int[] myPixels;
	private CloseNotify myNotify;

	private AndroidDrawer() {
		super();
	}

	/**
	 * Sets size of drawable area
	 */
	public void setSize(int x, int y) {
		myChanged = true;
		if (myPaint == null) {
			myPaint = new Paint();
			myPaint.setAntiAlias(true);
			myPaint.setARGB(255, 255, 255, 255);
		}
		if ((myBitmap == null)
				|| ((myBitmap.getHeight() != y) || (myBitmap.getWidth() != x))) {
			myBitmap = Bitmap.createBitmap(x, y, Bitmap.Config.RGB_565);
			myCanvas = new Canvas();
			myCanvas.setBitmap(myBitmap);
			myCanvas.drawBitmap(myBitmap, 0, 0, null);
		}
	}

	/**
	 * Draws circle
	 */
	public void drawCircle(int x, int y, int radius) {
		myChanged = true;
		myCanvas.drawCircle(x, y, radius, myPaint);
	}

	/**
	 * Return grawable object, which can be used by UI
	 */
	public Object getDrawable() {
		return myBitmap;
	}

	/**
	 * Printing text
	 */
	public void drawText(String text, int x, int y) {
		myChanged = true;
		myCanvas.drawText(text, x, y, myPaint);
	}

	/**
	 * Sets active color
	 */
	public void setColor(int alpha, int r, int g, int b) {
		myPaint.setARGB(alpha, r, g, b);
	}

	/**
	 * Draws line
	 */
	public void drawLine(int x0, int y0, int x1, int y1) {
		myChanged = true;
		myCanvas.drawLine(x0, y0, x1, y1, myPaint);
	}

	public void fastDrawLine(int x1, int y1, int x2, int y2, int color) {
		if (y1 > y2) {
			for (int i = y2; i <= y1; i++) {
				if ((x1 > 2) && (x1 < 100)) {
					myBitmap.setPixel(x1, i, color);
				}
			}
		} else {
			for (int i = y1; i <= y2; i++) {
				if ((x1 > 2) && (x1 < 1000)) {
					myBitmap.setPixel(x1, i, color);
				}
			}
		}
	}

	public void drawRectangle(int left, int top, int right, int bottom) {
		myChanged = true;
		myCanvas.drawRect(left, top, right, bottom, myPaint);
	}

	public void drawPoint(int x, int y) {
		myChanged = true;
		myCanvas.drawPoint(x, y, myPaint);
	}

	/**
	 * Returns true if something was drawn since last call of isCalled
	 */
	public boolean isChanged() {
		if (myChanged) {
			myChanged = false;
			return true;
		}
		return false;
	}

	/**
	 * returns aproximate width of the string on the screen
	 */
	public int measureTextWidth(String s) {
		Rect r = new Rect();
		myPaint.getTextBounds(s, 0, s.length(), r);
		return r.width();
	}

	public int measureTextHeight(String s) {
		Rect r = new Rect();
		myPaint.getTextBounds(s, 0, s.length(), r);
		return r.height();
	}

	public void saveFileDialog(RequestString action) {
		Intent intent = new Intent();
		myActionToDo = action;
		intent.setClass(myContext, SoundSaveDialog.class);
		myContext.startActivity(intent);
	}

	public static IDrawer getDrawer() {
		return AndroidDrawer.myDrawerInctance;
	}

	public static IDrawer getDrawer(Object context) {
		if (AndroidDrawer.myDrawerInctance == null) {
			AndroidDrawer.myDrawerInctance = new AndroidDrawer();
			AndroidDrawer.myDrawerInctance.myContext = (Context) context;
		}
		return AndroidDrawer.myDrawerInctance;
	}

	@Override
	/*
	 * public void showMessage(final String message, final String caption) {
	 * 
	 * Dialog d = new Dialog(myContext) { Dialog me;
	 * 
	 * @Override protected void onCreate(Bundle savedInstanceState) { me = this;
	 * super.onCreate(savedInstanceState); setTitle(caption); LinearLayout ll1 =
	 * new LinearLayout(myContext); TextView tv = new TextView(myContext);
	 * Button b = new Button(myContext);
	 * ll1.setOrientation(LinearLayout.VERTICAL); ll1.addView(tv, new
	 * LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
	 * 
	 * LinearLayout ll2 = new LinearLayout(myContext); ll2.addView(b, new
	 * LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
	 * 
	 * b.setText("Ok"); tv.setText(message); tv.setTextSize(tv.getTextSize() 3 /
	 * 2); setContentView(ll); b.setWidth(10);
	 * 
	 * b.setOnClickListener(new View.OnClickListener() { public void
	 * onClick(View v) { me.cancel(); } });
	 * 
	 * } }; d.show(); }
	 */
	/*
	 * AlertDialog.Builder builder = new AlertDialog.Builder(this);
	 * builder.setMessage("Are you sure you want to exit?")
	 * .setCancelable(false) .setPositiveButton("Yes", new
	 * DialogInterface.OnClickListener() { public void onClick(DialogInterface
	 * dialog, int id) { MyActivity.this.finish(); } }) .setNegativeButton("No",
	 * new DialogInterface.OnClickListener() { public void
	 * onClick(DialogInterface dialog, int id) { dialog.cancel(); } });
	 * AlertDialog alert = builder.create();
	 */
	public void showMessage(final String message) {

		AlertDialog.Builder builder = new AlertDialog.Builder(myContext);
		// builder.setMessage(message);
		builder.setTitle(message);
		builder.setCancelable(false);
		builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				// do nothing
			}
		});
		AlertDialog alert = builder.create();
		alert.show();
	}

	@Override
	public void drawPicture(int id, int x, int y) {
		Drawable icon = myContext.getResources().getDrawable(id);
		int w = icon.getMinimumWidth();
		int h = icon.getMinimumHeight();
		icon.setBounds(x, y, x + w, y + h);
		icon.draw(myCanvas);
		myChanged = true;
	}

	@Override
	public int getPictureHeight(int id) {
		Drawable icon = myContext.getResources().getDrawable(id);
		return icon.getMinimumHeight();
	}

	@Override
	public int getPictureWidth(int id) {
		Drawable icon = myContext.getResources().getDrawable(id);
		return icon.getMinimumWidth();
	}

	@Override
	public void showMessageWithCheckbox(String message, String checkboxMessage,
			final RequestBoolean action) {
		AlertDialog.Builder builder = new AlertDialog.Builder(myContext);
		builder.setTitle(message);
		builder.setCancelable(false);
		CheckBox ch = new CheckBox(myContext);
		ch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			public void onCheckedChanged(CompoundButton buttonView,
					boolean isChecked) {
				action.run(isChecked);
			}
		});
		ch.setText(checkboxMessage);
		builder.setView(ch);
		builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				// do nothing
			}
		});
		AlertDialog alert = builder.create();
		alert.show();
	}

	@Override
	public void drawBackground() {
		// TODO Auto-generated method stub
		if ((myPixels == null)
				|| (myBitmap.getWidth() * myBitmap.getHeight() != myPixels.length)) {
			System.out.println("bad pixels");
		} else {
			myBitmap.setPixels(myPixels, 0, myBitmap.getWidth(), 0, 0, myBitmap
					.getWidth(), myBitmap.getHeight());
			myCanvas.drawBitmap(myBitmap, 0, 0, null);
		}
	}

	@Override
	public void saveBackgroud() {
		if ((myPixels == null)
				|| (myBitmap.getWidth() * myBitmap.getHeight() != myPixels.length)) {
			myPixels = new int[myBitmap.getWidth() * myBitmap.getHeight()];
		}
		myBitmap.getPixels(myPixels, 0, myBitmap.getWidth(), 0, 0, myBitmap
				.getWidth(), myBitmap.getHeight());

	}

	@Override
	public void hideProgressDialog() {
		if (myNotify == null) {
			return;
		}
		myNotify.myDialog.cancel();
	}

	@Override
	synchronized public void showProgressDialog(final String title,
			final String message) {
		myNotify = new CloseNotify();
		myNotify.myFlag = false;
		myNotify.myDialog = null;
		new Thread(new Runnable() {
			@Override
			public void run() {
				Looper.prepare();
				synchronized (myNotify) {
					if (!myNotify.myFlag) {
						myNotify.myDialog = ProgressDialog.show(myContext,
								title, message, true);
						myNotify.myDialog.setProgress(100);

					}
				}
				Looper.loop();
			}
		}).start();
	}

	@Override
	public void showBooleanRequest(String text, final RequestBoolean action) {
		AlertDialog.Builder builder = new AlertDialog.Builder(myContext);
		builder.setTitle(text);
		builder.setCancelable(false);
		builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				action.run(true);
			}
		});
		builder.setNegativeButton("Cancel",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						action.run(false);
					}
				});
		AlertDialog alert = builder.create();
		alert.show();

	}

}

class CloseNotify {
	public ProgressDialog myDialog;
	public boolean myFlag;
}
